#include "AnaDef.h"
#include "AnaAliDef.h"
#include "AliAnalysisTaskSE.h"
#include "AliAnalysisAlien.h"

Bool_t fkTest = kTRUE;
Int_t fID = -999;

//Warning in <AliAnalysisAlien::SetRunMode>: Run mode "init" not known. Supported modes: "full", "test", "offline", "submit" and "merge"
//Warning in <AliAnalysisAlien::SetRunMode>: Run mode set to FULL
//I-AliAnalysisAlien::StartAnalysis: 
//#### STARTING AN ALIEN SHELL FOR YOU. EXIT WHEN YOUR JOB  HAS FINISHED. ####    
//You may exit at any time and terminate the job later using the option <terminate>    
//
void Load();
AliAnalysisGrid* CreateAlienHandler(const char *taskname, const char * gridmode);

void runPlugIn(const bool ktest, const char*gridmode, const char *taskname = "AODpkRaa")
{
  fkTest = ktest;

  if(strcmp(gridmode,"full") && strcmp(gridmode,"merge") && strcmp(gridmode,"terminate")){
    printf("wrong gridmode %s\n", gridmode); 
    return;
  }

  TString pwd=gSystem->pwd();
  pwd.ReplaceAll("ID","@");
  const Int_t kk = pwd.First("@");
  pwd=pwd(kk+1,10);
  if(kk>0){
    fID=atoi(pwd.Data());
  }

  if(fID<=0){
    printf("fID<0!! %d %s %s\n", fID, gSystem->pwd(), pwd.Data()); exit(1);
  }

  printf("************************\n\n");
  printf("       fkTest %d fID %d gridmode %s\n", fkTest, fID, gridmode);
  printf("************************\n\n");

  Load();

  AliAnalysisManager* mgr = new AliAnalysisManager(Form("%s-Manager",taskname));

  AliAnalysisGrid *plugin = CreateAlienHandler(taskname, gridmode);
  mgr->SetGridHandler(plugin);

  mgr->SetInputEventHandler(new AliAODInputHandler);

  gROOT->LoadMacro(Form("AliAnalysisTask%s.cxx+g", taskname));        
  Long_t r = gROOT->ProcessLine(Form("new AliAnalysisTask%s",taskname));
  AliAnalysisTaskSE* task = reinterpret_cast<AliAnalysisTaskSE*>(r);
  mgr->AddTask(task);
        
  AliAnalysisDataContainer *cinput  = mgr->GetCommonInputContainer();
  mgr->ConnectInput(task,  0, cinput );
  
  const TString foutname=Form("xlu_%s",taskname);
  AliAnalysisDataContainer *outlist1 = mgr->CreateContainer("xlu_tree",            TTree::Class(), AliAnalysisManager::kOutputContainer,foutname+"_tree.root");
  AliAnalysisDataContainer *outlist2 = mgr->CreateContainer("xlu_list",            TList::Class(), AliAnalysisManager::kOutputContainer,foutname+"_hist.root");        
  //in AnalysisTaskSE, slot 0 reserved, must start from 1
  task->ConnectOutput(1, outlist1);
  task->ConnectOutput(2, outlist2);
  
  // enable debug printouts
  mgr->SetDebugLevel(2);
  //mgr->SetNSysInfo(100);
  if (!mgr->InitAnalysis()) return;
  mgr->PrintStatus();
  
  Printf("Starting Analysis....");
  mgr->StartAnalysis("grid");
}

AliAnalysisGrid* CreateAlienHandler(const char *taskname, const char * gridmode)
{
  AliAnalysisAlien *plugin = new AliAnalysisAlien();

  //========================================================================================
  //                      check
  //========================================================================================
  plugin->SetGridDataDir("/alice/data/2011/LHC11h_2");
  
  //must be called before AddRunNumber!!
  plugin->SetRunPrefix("000");   // real data

  if(fkTest){
    plugin->SetDataPattern("ESDs/pass2/AOD095/0001/AliAOD.root -name ESDs/pass2/AOD095/0002/AliAOD.root");
    plugin->AddRunNumber(169156);

    plugin->SetSplitMaxInputFileNumber(1);
    plugin->SetNrunsPerMaster(200);
  }
  else {	
    plugin->SetDataPattern("ESDs/pass2/AOD095/*/AliAOD.root");
    const Int_t runlist[]={170593,170572,170388,170387,170315,170313,170312,170311,170309,170308,170306,170270,170269,170268,170230,170228,170207,170204,170203,170193,170163,170159,170155,170091,170089,170088,170085,170084,170083,170081,170040,170027,169965,169923,169859,169858,169855,169846,169838,169837,169835,169591,169590,169588,169587,169586,169557,169555,169554,169553,169550,169515,169512,169506,169504,169498,169475,169420,169419,169418,169417,169415,169411,169238,169167,169160,169156,169148,169145,169144,169138,169099,169094,169091,169045,169044,169040,169035,168992,168988,168826,168777,168514,168512,168511,168467,168464,168460,168458,168362,168361,168342,168341,168325,168322,168311,168310,168115,168108,168107,168105,168076,168069,167988,167987,167985,167920,167915};
    
    //nchunk AOD095 108 good run 1.2e5 chunk
    const Int_t nrun = sizeof(runlist)/sizeof(Int_t);
    printf("nrun: %d\n", nrun);
    for (Int_t ind=0; ind<nrun; ind++) {
      plugin->AddRunNumber(runlist[ind]);
    }

    plugin->SetSplitMaxInputFileNumber(100);
    plugin->SetNrunsPerMaster(60);
  }
  
  plugin->SetAPIVersion("V1.1x");
  plugin->SetROOTVersion("v5-34-01-1");
  plugin->SetAliROOTVersion("v5-02-Rev-23");

  
  //========================================================================================
  //                       don't care
  //========================================================================================
  
  plugin->SetOverwriteMode();
  plugin->SetRunMode(gridmode);
  plugin->SetMergeViaJDL(kTRUE);
  
  plugin->SetGridWorkingDir(Form("Analysis_ID%d",fID));
  plugin->SetGridOutputDir("output"); 
  plugin->SetExecutable(Form("analysis_ID%d.sh",fID));
  plugin->SetJDLName(Form("analysis_ID%d.jdl",fID));
  plugin->SetAnalysisMacro(Form("analysis_ID%d.C",fID));

  plugin->SetAnalysisSource(Form("AliAnalysisTask%s.cxx", taskname));
  plugin->SetAdditionalLibs(Form("libGui.so libCore.so libTree.so libPhysics.so libMinuit.so libProof.so libmicrocern.so liblhapdf.so libpythia6.so libEG.so libGeom.so libVMC.so libEGPythia6.so libSTEERBase.so libESD.so libRAWDatabase.so libRAWDatarec.so libAOD.so libANALYSIS.so libANALYSISalice.so libCDB.so libSTEER.so libRAWDatasim.so libFASTSIM.so libEVGEN.so libAliPythia6.so libSTAT.so libhijing.so libTHijing.so libSTRUCT.so libPHOSUtils.so libPHOSbase.so libPHOSsim.so libPHOSrec.so libMUONcore.so libMUONmapping.so libMUONgeometry.so libMUONcalib.so libMUONraw.so libMUONtrigger.so libMUONbase.so libMUONsim.so libMUONrec.so libMUONevaluation.so libFMDbase.so libFMDsim.so libFMDrec.so libPMDbase.so libPMDsim.so libPMDrec.so libHMPIDbase.so libHMPIDsim.so libHMPIDrec.so libT0base.so libT0sim.so libT0rec.so libZDCbase.so libZDCsim.so libZDCrec.so libACORDEbase.so libACORDErec.so libACORDEsim.so libVZERObase.so libVZEROrec.so libVZEROsim.so libEMCALraw.so libEMCALUtils.so libEMCALbase.so libEMCALsim.so libEMCALrec.so libTPCbase.so libTPCrec.so libTPCsim.so libTPCfast.so libITSbase.so libITSsim.so libITSrec.so libTRDbase.so libTRDsim.so libTRDrec.so libTOFbase.so libTOFrec.so libTOFsim.so libHLTbase.so libHLTinterface.so libHLTsim.so libHLTrec.so libTENDER.so libTENDERSupplies.so libPWGPP.so \
 AliAnalysisTask%s.h AliAnalysisTask%s.cxx", taskname, taskname));
  
  return plugin;
}

int main(int argc, char * argv[])
{
  for(int ii=0; ii<argc; ii++){
    printf("%d: %s\n", ii, argv[ii]);
  }

  if(argc!=3){
    printf("argc!=3 \n");
    return 1;
  }

  runPlugIn(atoi(argv[1]), argv[2]);
  return 0;
}


void Load()
{// load libraries (to be optimized)
	gSystem->Load("libCore.so");
	gSystem->Load("libTree.so");
	gSystem->Load("libPhysics");
	gSystem->Load("libMinuit");
	gSystem->Load("libProof");
	gSystem->Load("libmicrocern");
	gSystem->Load("liblhapdf");
	gSystem->Load("libpythia6");
	gSystem->Load("libEG");
	gSystem->Load("libGeom");
	gSystem->Load("libVMC");
	gSystem->Load("libEGPythia6");
	gSystem->Load("libSTEERBase");
	gSystem->Load("libESD");
	gSystem->Load("libCDB");
	gSystem->Load("libRAWDatabase");
	gSystem->Load("libRAWDatarec");
	gSystem->Load("libAOD");
	gSystem->Load("libANALYSIS");
	gSystem->Load("libANALYSISalice");
	gSystem->Load("libSTEER");
	gSystem->Load("libTENDER");
	gSystem->Load("libRAWDatasim");
	gSystem->Load("libFASTSIM");
	gSystem->Load("libEVGEN");
	gSystem->Load("libAliPythia6");
	gSystem->Load("libSTAT");
	gSystem->Load("libhijing");
	gSystem->Load("libTHijing");
	gSystem->Load("libSTRUCT");
	gSystem->Load("libPHOSUtils");
	gSystem->Load("libPHOSbase");
	gSystem->Load("libPHOSsim");
	gSystem->Load("libPHOSrec");
	gSystem->Load("libMUONcore");
	gSystem->Load("libMUONmapping");
	gSystem->Load("libMUONgeometry");
	gSystem->Load("libMUONcalib");
	gSystem->Load("libMUONraw");
	gSystem->Load("libMUONtrigger");
	gSystem->Load("libMUONbase");
	gSystem->Load("libMUONsim");
	gSystem->Load("libMUONrec");
	gSystem->Load("libMUONevaluation");
	gSystem->Load("libFMDbase");
	gSystem->Load("libFMDsim");
	gSystem->Load("libFMDrec");
	gSystem->Load("libPMDbase");
	gSystem->Load("libPMDsim");
	gSystem->Load("libPMDrec");
	gSystem->Load("libHMPIDbase");
	gSystem->Load("libHMPIDsim");
	gSystem->Load("libHMPIDrec");
	gSystem->Load("libT0base");
	gSystem->Load("libT0sim");
	gSystem->Load("libT0rec");
	gSystem->Load("libZDCbase");
	gSystem->Load("libZDCsim");
	gSystem->Load("libZDCrec");
	gSystem->Load("libACORDEbase");
	gSystem->Load("libACORDErec");
	gSystem->Load("libACORDEsim");
	gSystem->Load("libVZERObase");
	gSystem->Load("libVZEROrec");
	gSystem->Load("libVZEROsim");
	gSystem->Load("libEMCALraw");
	gSystem->Load("libEMCALUtils");
	gSystem->Load("libEMCALbase");
	gSystem->Load("libEMCALsim");
	gSystem->Load("libEMCALrec");
	gSystem->Load("libTPCbase");
	gSystem->Load("libTPCrec");
	gSystem->Load("libTPCsim");
	gSystem->Load("libTPCfast");
	gSystem->Load("libITSbase");
	gSystem->Load("libITSsim");
	gSystem->Load("libITSrec");
	gSystem->Load("libTRDbase");
	gSystem->Load("libTRDsim");
	gSystem->Load("libTRDrec");
	gSystem->Load("libTOFbase");
	gSystem->Load("libTOFrec");
	gSystem->Load("libTOFsim");
	gSystem->Load("libHLTbase");
	gSystem->Load("libHLTinterface");
	gSystem->Load("libHLTsim");
	gSystem->Load("libHLTrec");
	gSystem->Load("libPWGPP");

        gSystem->Load("libANALYSISalice");

        gSystem->AddIncludePath("-I$ALICE_ROOT/include");
}
